#include "Sock.hpp"
#include "Protocol.hpp"
#include "TcpClient.hpp"
#include <iostream>
#include <string>

using namespace protocol_ns;

static void usage(std::string proc){
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

enum{
    LEFT,
    OPER,
    RIGHT
};

Request ParseLine(string& line){
    string left, right;
    char op;
    int status = LEFT;

    int i = 0;
    while(i < line.size()){
        switch (status)
        {
        case LEFT:
            if(isdigit(line[i]))
                left.push_back(line[i++]);
            else
                status = OPER;
            break;
        case OPER:
            op = line[i++];
            status = RIGHT;
            break;
        case RIGHT:
            if (isdigit(line[i]))
                right.push_back(line[i++]);
            break;
        }
    }

    Request req;
    req._x = stoi(left);
    req._y = stoi(right);
    req._op = op;

    return req;
}

int main(int argc, char* argv[]){
    if(argc != 3){
        usage(argv[0]);
        exit(USAGE_ERR);
    }
    string serverIp = argv[1];
    uint16_t serverPort = atoi(argv[2]);

    Sock sock;
    sock.Socket();

    int n = sock.Connect(serverIp, serverPort);
    if(n != 0)
        return 1;
    
    string buffer;
    while(true){
        cout << "Enter# ";
        string line;
        getline(cin, line);
        Request req = ParseLine(line);

        //序列化
        string sendString;
        req.Serialize(&sendString);
        //添加报头
        sendString = AddHeader(sendString);
        //发送
        send(sock.GetSock(), sendString.c_str(), sendString.size(), 0);
        //获取响应,拿到完整response string
        string package;
        int n = 0;
    START:
        n = ReadPackage(sock.GetSock(), buffer, &package);
        if(n == 0)
            goto START;
        else if(n < 0)
            break;
        else{

        }

        //去报头
        package = RemoveHeader(package, n);
        //反序列化
        Response res;
        res.Deserialize(package);
        
        std::cout << "result: " << res._result << "[code: " << res._code << "]" << std::endl;
    }
    sock.Close();
    return 0;
}